// 结构化类型系统: 类型兼容性判断的幕后

// 标称类型系统

// 类型别名 == 泛型;
type USD = number;
type CNY = number;

const CNYCount: CNY = 200;
const USDCount: USD = 200;

function addCNY(source: CNY, input: CNY) {
    return source + input;
}

addCNY(CNYCount, USDCount)

class Cat { };
// 实现一只短毛猫!
class ShorthairCat extends Cat { }

// 在TypeScript 中模拟标称类型系统;

// 通过交叉类型 实现附加;
/* 
    declare 可以成名一个类型
            声明一个模块
            声明一个变量
            声明一个作用域
            在type前 (declare type == type)  

*/
export declare class TagProtector<T extends string> {
    // protected 访问修饰符 内部和子类可访问, 外部禁止访问;
    protected __tag__ : T;
}
// 导出 类型别名
export type Nominal<T, U extends string> = T & TagProtector<U>;

// Nominal 工具类型;
export type CNY1 = Nominal<number, 'CNY'>;
export type USD1 = Nominal<number, 'USD'>;
const CNYCount1 = 100 as CNY;
const USDCount1 = 100 as USD;

function addCNY1(source: CNY1, input: CNY1) {
    return (source + input) as CNY;
}
// addCNY1(CNYCount, CNYCount);

// 报错了! 
addCNY(CNYCount, USDCount);

addCNY(CNYCount, USDCount);


